package wgetservice

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"strconv"

	//"rbac-admin/common/helper"
	"time"
)

type NetService struct {
}

func NewNetService() NetService {
	return NetService{}
}

func (s *NetService) Get(url string) []byte {

	// 超时时间：5秒
	client := &http.Client{Timeout: 5 * time.Second}
	resp, err := client.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	var buffer [512]byte
	result := bytes.NewBuffer(nil)
	for {
		n, err := resp.Body.Read(buffer[0:])
		result.Write(buffer[0:n])
		if err != nil && err == io.EOF {
			break
		} else if err != nil {
			panic(err)
		}
	}

	return []byte(result.String())
}

/*
 * Curl crul调用公共方法 请求统一走json传参
 * method 请求类型  0:Get 1:Post
 * protocol 请求协议
 * host 请求域名
 * url 请求的路由
 * header 请求的header头
 * params 请求的参数
 * r 请求数据
 * KafkaWriterLog 日志写入对象
 */

func (s *NetService) Curl(method string, url string, header map[string]string, params interface{}) ([]byte, error) {
	client := &http.Client{
		Timeout: 20 * time.Second,
	}
	var request *http.Request
	var err error
	fmt.Println("Curl: ", ToString(params))
	jsonData, err := json.Marshal(params)
	if err != nil {
		return nil, err
	}
	//url = protocol + host + url
	request, err = http.NewRequest(method, url, bytes.NewReader(jsonData))
	if err != nil {
		return nil, err
	}
	if header == nil {
		header = make(map[string]string)
	}
	if len(header) > 0 {
		for k, v := range header {
			request.Header.Add(k, v)
		}
	}
	request.Header.Add("Content-Type", "application/json")
	resp, err := client.Do(request)
	if err != nil {
		return nil, err
	}
	if nil == resp {
		return nil, errors.New(url + "external_api curl resp" + "查询返回nill")
	}
	defer resp.Body.Close()
	bodyContent, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	sprintf := fmt.Sprintf("Curl:%v method:%+v url:%+v header:%+v postData:%+v bodyContent:%+v", time.Now().Format(time.DateTime), method, url, header, params, ToString(bodyContent))
	zap.L().Info(sprintf)
	return bodyContent, nil
}
func (s *NetService) PostWithFormData(method, url string, header map[string]string, postData *map[string]string) ([]byte, error) {
	body := new(bytes.Buffer)
	w := multipart.NewWriter(body)
	for k, v := range *postData {
		w.WriteField(k, v)
	}
	w.Close()
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}
	if header == nil {
		header = make(map[string]string)
	}
	if len(header) > 0 {
		for k, v := range header {
			req.Header.Add(k, v)
		}
	}
	req.Header.Set("Content-Type", w.FormDataContentType())
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	bodyContent, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	fmt.Println(resp.StatusCode)
	fmt.Printf("%s", bodyContent)
	//收集记录数据
	sprintf := fmt.Sprintf("PostWithFormData:%v method:%+v url:%+v postData:%+v bodyContent:%+v", time.Now().Format(time.DateTime), method, url, *postData, ToString(bodyContent))
	zap.L().Info(sprintf)
	return bodyContent, nil
}

func RobotCurlBase(method string, protocol string, host string, url string, header map[string]string, params interface{}) (interface{}, error) {
	client := &http.Client{
		Timeout: 20 * time.Second,
	}
	var request *http.Request
	var err error

	fmt.Println("Curl: ", ToString(params))

	jsonData, err := json.Marshal(params)
	if err != nil {
		return nil, err
	}
	url = protocol + host + url
	request, err = http.NewRequest(method, url, bytes.NewReader(jsonData))

	if err != nil {
		return nil, err
	}
	if len(header) > 0 {
		for k, v := range header {
			request.Header.Add(k, v)
		}
	}
	request.Header.Add("Content-Type", "application/json")
	resp, err := client.Do(request)
	if err != nil {
		return nil, err
	}
	if nil == resp {
		return "", errors.New(url + "external_api curl resp" + "查询返回nill")
	}

	defer resp.Body.Close()
	bodyContent, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	return bodyContent, nil
}

// RobotCurl 群机器人
func (s *NetService) RobotCurl(method string, url string, header map[string]string, params map[string]interface{}) (interface{}, error) {
	if method == "" {
		method = "POST"
	}
	protocol := "https://"
	return RobotCurlBase(method, protocol, "", url, header, params)
}

func ToString(value interface{}) string {
	// interface 转 string
	var key string
	if value == nil {
		return key
	}
	switch value.(type) {
	case float64:
		ft := value.(float64)
		key = strconv.FormatFloat(ft, 'f', -1, 64)
	case float32:
		ft := value.(float32)
		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
	case int:
		it := value.(int)
		key = strconv.Itoa(it)
	case uint:
		it := value.(uint)
		key = strconv.Itoa(int(it))
	case int8:
		it := value.(int8)
		key = strconv.Itoa(int(it))
	case uint8:
		it := value.(uint8)
		key = strconv.Itoa(int(it))
	case int16:
		it := value.(int16)
		key = strconv.Itoa(int(it))
	case uint16:
		it := value.(uint16)
		key = strconv.Itoa(int(it))
	case int32:
		it := value.(int32)
		key = strconv.Itoa(int(it))
	case uint32:
		it := value.(uint32)
		key = strconv.Itoa(int(it))
	case int64:
		it := value.(int64)
		key = strconv.FormatInt(it, 10)
	case uint64:
		it := value.(uint64)
		key = strconv.FormatUint(it, 10)
	case string:
		key = value.(string)
	case []byte:
		key = string(value.([]byte))
	default:
		newValue, _ := json.Marshal(value)
		key = string(newValue)
	}
	return key
}
